home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-07-16 | 41.8 KB | 1,251 lines |
- ;;;
- ;;; Copyright (c) 1986 Texas Instruments Incorporated
- ;;;
- ;;; Permission to copy this software, to redistribute it, and
- ;;; to use it for any purpose is granted, subject to the
- ;;; following restrictions and understandings.
- ;;;
- ;;; 1. Any copy made of this software must include this copyright
- ;;; notice in full.
- ;;;
- ;;; 2. All materials developed as a consequence of the use of
- ;;; this software shall duly acknowledge such use, in accordance
- ;;; with the usual standards of acknowledging credit in academic
- ;;; research.
- ;;;
- ;;; 3. TI has made no warranty or representation that the
- ;;; operation of this software will be error-free, and TI is
- ;;; under no obligation to provide any services, by way of
- ;;; maintenance, update, or otherwise.
- ;;;
- ;;; 4. In conjunction with products arising from the use
- ;;; of this material, there shall be no use of the name of
- ;;; Texas Instruments (except for the above copyright credit)
- ;;; nor of any adaptation thereof in any advertising, promotional,
- ;;; or sales literature without prior written consent from TI in
- ;;; each case.
- ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;;; --- Modified SCOOPS taken from archive at altdorf.ai.mit.edu to make
- ;;; it work with MIT Scheme 7.1, 6 May 1991 - Peter Ross, Dept of AI,
- ;;; University of Edinburgh, Scotland; peter@aipna.ed.ac.uk
- ;;;
- ;;; Several small mods had to be made to Steve Sherin's version for
- ;;; Scheme 6.2, as patched and found in the archive at altdorf. Summary:
- ;;; - it turned out that the class compilation had NEVER (!?) worked
- ;;; correctly; the function %sc-method-thrust evaluated each method
- ;;; in the environment returned by (%sc-method-env class), by iterating
- ;;; over method info in (%sc-method-values class). That contained only
- ;;; those methods which had been explicitly attached to the class, not
- ;;; any which where inherited from mixins too. The only information
- ;;; about mixin methods, before class compilation time, resides in
- ;;; what (%sc-method-struct class) returns. So %sc-method-thrust has
- ;;; been changed to make it work correctly.
- ;;; - the macros were set up by syntax-table-define, so took effect
- ;;; at load time; even those which were needed at system compile time.
- ;;; The MIT Scheme Support Team contributed the notion of
- ;;; define-macro-both, which is defined both by syntax-table-define
- ;;; and define-macro and which defines a macro both ways. Tedious
- ;;; but probably wiser as a defence for anybody who might want to
- ;;; compile SCOOPS together with their own stuff some day.
- ;;; - removed a couple of the silly macros
- ;;; - cleaned up usage of #t/#!true etc. Note that #f is still
- ;;; the same as the empty list in MIT Scheme 7.1, despite what
- ;;; the Scheme standard says, and #f prints as () by default.
- ;;; - the original had this odd macro:
- ;;; (syntax-table-define user-initial-syntax-table 'REC
- ;;; (macro (name lambda-exp)
- ;;; `(begin (define ,name ,lambda-exp) ,name)))
- ;;; which is, alas, not legal Scheme (define at start of a begin
- ;;; but a begin is not a lambda body). Interestingly, SF passed
- ;;; this but Liar barfed on it. However, the macro seems to have
- ;;; existed because of the stylistic sense of somebody somewhere
- ;;; who was brought up on CL-type ITERATE macros (not Steve Sherin,
- ;;; since REC exists as such in PC-Scheme). Edited it out.
- ;;;
- ;;; So now the .scm, .bin and .com versions should all work correctly.
- ;;; But I had very few examples of SCOOPS use on which to test them,
- ;;; so don't curse me if you find another bug. Tell me instead...
- ;;;
- ;;; See scoops.txt for some user documentation.
- ;;;
- ;;; Many thanks to the MIT Scheme Support Team, whose responsiveness
- ;;; to my queries was excellent.
-
-
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; ;;;
- ;;; S c o o p s ;;;
- ;;; ;;;
- ;;; File updated : 5/23/86 ;;;
- ;;; ;;;
- ;;; File : class.scm ;;;
- ;;; ;;;
- ;;; Amitabh Srivastava ;;;
- ;;; ;;;
- ;;; This file handles class creation. ;;;
- ;;; ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (declare (usual-integrations))
-
- (define ALL-CLASSVARS)
- (define ALL-INSTVARS)
- (define ALL-METHODS)
- (define CLASS-COMPILED?)
- (define CLASSVARS)
- (define DESCRIBE)
- (define INSTVARS)
- (define METHODS)
- (define MIXINS)
-
- ;;; These definitions are to bring scoops up to date with MIT Scheme 7.1
-
- (define parser-package (->environment (find-package '(runtime parser))))
- (define unparser-package (->environment (find-package '(runtime unparser))))
- (define environment-package (->environment
- (find-package '(runtime environment))))
- (define (writeln . objects)
- (newline)
- (for-each display objects))
-
- ;;; Following hack courtesy of MIT Scheme support team:
- ;;; define-macro is for the compile-time stuff,
- ;;; syntax-table-define stuff does not tacke effect
- ;;; until load time.
- ;;; So to get a macro to take effect at compile time and
- ;;; also make it available at load time, use this:
-
- (define-macro (define-macro-both params . body)
- (let ((name (car params))
- (params* (cdr params)))
- `(begin
- (define-macro ,params ,@body)
- (syntax-table-define user-initial-syntax-table ',name
- (macro ,params* ,@body)))))
-
- (syntax-table-define system-global-syntax-table 'define-macro-both
- (macro (pattern . body)
- `(begin
- (define-macro ,pattern ,@body)
- (syntax-table-define user-initial-syntax-table ',(car pattern)
- (macro ,(cdr pattern)
- ,@body)))))
-
- ;;;
-
- (define %%class-tag (intern "#!CLASS"))
-
- (set! (access named-objects parser-package)
- (cons (cons 'CLASS %%class-tag) (access named-objects parser-package)))
-
-
- ((access add-unparser-special-object! unparser-package) %%class-tag
- (lambda (class)
- ((access unparse-with-brackets unparser-package)
- (lambda ()
- (write-string "SCOOPS Class ")
- (write (hash class))))))
-
-
- (define %sc-make-class
- (lambda (name cv allivs mixins method-values)
- (let ((method-structure
- (map (lambda (a) (list (car a) (cons name name)))
- method-values))
- (class (make-vector 15)))
- (vector-set! class 0 %%class-tag)
- (vector-set! class 1 name)
- (vector-set! class 2 cv)
- (vector-set! class 3 cv)
- (vector-set! class 4 allivs)
- (vector-set! class 5 mixins)
- (vector-set! class 6 (%uncompiled-make-instance class))
- (vector-set! class 9 method-structure)
- (vector-set! class 13 method-values)
- (vector-set! class 14 allivs)
- (2d-put! name '%class class)
- class)))
-
- (define %scoops-chk-class
- (lambda (class)
- (and (not (and (vector? class)
- (> (vector-length class) 0)
- (equal? %%class-tag (vector-ref class 0))))
- (error-handler class 6 #t))))
-
-
- ;;; %sc-name
- (define-integrable (%sc-name class)
- (vector-ref class 1))
-
- ;;; %sc-cv
- (define-integrable (%sc-cv class)
- (vector-ref class 2))
-
- ;;; %sc-allcvs
- (define-integrable (%sc-allcvs class)
- (vector-ref class 3))
-
- ;;; %sc-allivs
- (define-integrable (%sc-allivs class)
- (vector-ref class 4))
-
- ;;; %sc-mixins
- (define-integrable (%sc-mixins class)
- (vector-ref class 5))
-
- ;;; %sc-inst-template
- (define-integrable (%sc-inst-template class)
- (vector-ref class 6))
-
- ;;; %sc-method-env
- (define-integrable (%sc-method-env class)
- (vector-ref class 7))
-
- ;;; %sc-class-env
- (define-integrable (%sc-class-env class)
- (vector-ref class 8))
-
-
- ;;; %sc-method-structure
- (define-integrable (%sc-method-structure class)
- (vector-ref class 9))
-
- ;;; %sc-subclasses
- (define-integrable (%sc-subclasses class)
- (vector-ref class 10))
-
- ;;; %sc-class-compiled
- (define-integrable (%sc-class-compiled class)
- (vector-ref class 11))
-
- ;;; %sc-class-inherited
- (define-integrable (%sc-class-inherited class)
- (vector-ref class 12))
-
- ;;; %sc-method-values
- (define-integrable (%sc-method-values class)
- (vector-ref class 13))
-
- (define-integrable (%sc-iv class)
- (vector-ref class 14))
-
- ;;; %sc-set-name
- (define-integrable (%sc-set-name class val)
- (vector-set! class 1 val))
-
- ;;; %sc-set-cv
- (define-integrable (%sc-set-cv class val)
- (vector-set! class 2 val))
-
-
- ;;; %sc-set-allcvs
- (define-integrable (%sc-set-allcvs class val)
- (vector-set! class 3 val))
-
- ;;; %sc-set-allivs
- (define-integrable (%sc-set-allivs class val)
- (vector-set! class 4 val))
-
- ;;; %sc-set-mixins
- (define-integrable (%sc-set-mixins class val)
- (vector-set! class 5 val))
-
- ;;; %sc-set-inst-template
- (define-integrable (%sc-set-inst-template class val)
- (vector-set! class 6 val))
-
- ;;; %sc-set-method-env
- (define-integrable (%sc-set-method-env class val)
- (vector-set! class 7 val))
-
- ;;; %sc-set-class-env
- (define-integrable (%sc-set-class-env class val)
- (vector-set! class 8 val))
-
- ;;; %sc-set-method-structure
- (define-integrable (%sc-set-method-structure class val)
- (vector-set! class 9 val))
-
- ;;; %sc-set-subclasses
- (define-integrable (%sc-set-subclasses class val)
- (vector-set! class 10 val))
-
-
- ;;; %sc-set-class-compiled
- (define-integrable (%sc-set-class-compiled class val)
- (vector-set! class 11 val))
-
- ;;; %sc-set-class-inherited
- (define-integrable (%sc-set-class-inherited class val)
- (vector-set! class 12 val))
-
- ;;; %sc-set-method-values
- (define-integrable (%sc-set-method-values class val)
- (vector-set! class 13 val))
-
- ;;; %sc-set-iv
- (define-integrable (%sc-set-iv class val)
- (vector-set! class 14 val))
-
-
- ;;;
- (define %sc-name->class
- (lambda (name)
- (cond ((2d-get name '%class) => (lambda (a) a))
- (else (error-handler name 2 #t)))))
-
- ;;; %sc-get-meth-value
- (define-integrable (%sc-get-meth-value meth-name class)
- (cdr (assq meth-name (%sc-method-values class))))
-
- ;;; %sc-get-cv-value
- (define-integrable (%sc-get-cv-value var class)
- (cadr (assq var (%sc-cv class))))
-
- ;;; %sc-concat
- (define-integrable (%sc-concat str sym)
- (intern (string-append str (symbol->string sym))))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; ;;;
- ;;; S c o o p s ;;;
- ;;; ;;;
- ;;; ;;;
- ;;; Rewritten 5/20/87 for cscheme ;;;
- ;;; by Steve Sherin--U of P ;;;
- ;;; File : methods.scm ;;;
- ;;; ;;;
- ;;; Amitabh Srivastava ;;;
- ;;; ;;;
- ;;; This file handles the addition/redefinition of methods. ;;;
- ;;; ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
- ;;; is class1 before class2 in class ?
- ;;; class1 is not equal to class2
-
- (define %before
- (lambda (class1 class2 class)
- (or (eq? class1 class)
- (memq class2 (memq class1 (%sc-mixins (%sc-name->class class)))))))
-
- ;;; DEFINE-METHOD
- (syntax-table-define user-initial-syntax-table 'define-method
- (macro e
- (let ((class-name (caar e))
- (method-name (cadar e))
- (formal-list (cadr e))
- (body (cddr e)))
- `(%sc-class-add-method
- ',class-name
- ',method-name
- ',class-name
- ',class-name
- (append (list 'lambda ',formal-list) ',body)
- (lambda (env quoted-val)
- (let* ((method-name ',method-name)
- (temp `(in-package ,env
- (define ,method-name
- ,quoted-val))))
- (eval temp (the-environment)))
- )))))
- ;;;
-
- (define %sc-class-add-method
- (lambda (class-name
- method-name
- method-class
- mixin-class
- method
- assigner)
- (let ((class (%sc-name->class class-name)))
- (begin
- (let ((temp (assq method-name (%sc-method-values class))))
- (if temp
- (set-cdr! temp method)
- (%sc-set-method-values
- class
- (cons (cons method-name method) (%sc-method-values class))))))
- (%compiled-add-method class-name method-name method-class mixin-class
- method assigner))))
- ;;;
-
- (define %inform-subclasses
- (lambda (class-name method-name method-class mixin-class method assigner)
- (define loop
- (lambda (class-name method-name method-class mixin-class
- method assigner subclass)
- (if subclass
- (begin
- (%compiled-add-method
- (car subclass) method-name method-class class-name
- method assigner)
- (loop class-name method-name method-class mixin-class
- method assigner
- (cdr subclass))))))
- (loop class-name method-name method-class mixin-class method assigner
- (%sc-subclasses (%sc-name->class class-name)))))
- ;;;
-
- (define %compiled-add-method
- (lambda (class-name
- method-name
- method-class
- mixin-class
- method
- assigner)
- (letrec
- ((class (%sc-name->class class-name))
-
- (insert-entry
- (lambda (previous current)
- (cond ((null? current)
- (set-cdr! previous
- (cons (cons method-class mixin-class) '())))
- ((eq? mixin-class (cdar current))
- (set-car! (car current) method-class))
- ((%before mixin-class (cdar current)
- class-name)
- (set-cdr! previous
- (cons (cons method-class mixin-class) current)))
- (else '()))))
-
-
- (loop-insert
- (lambda (previous current)
- (if (not (insert-entry previous current))
- (loop-insert (current) (cdr current)))))
-
- (insert
- (lambda (entry)
- (if (insert-entry entry (cdr entry)) ;;; insert at head
- (add-to-environment)
- (loop-insert (cdr entry) (cddr entry)))))
-
- (add-to-environment
- (lambda ()
- (begin
- (if (%sc-class-compiled class)
- (assigner (%sc-method-env class) method))
- (if (%sc-subclasses class)
- (%inform-subclasses class-name method-name method-class
- mixin-class method assigner)))))
-
- (add-entry
- (lambda ()
- (begin
- (%sc-set-method-structure class
- (cons (list method-name (cons method-class mixin-class))
- (%sc-method-structure class)))
- (add-to-environment))))
- )
-
- (let ((method-entry (assq method-name (%sc-method-structure class))))
- (if method-entry
- (insert method-entry)
- (add-entry))
- method-name))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; ;;;
- ;;; S c o o p s ;;;
- ;;; ;;;
- ;;; ;;;
- ;;; Rewritten 5/20/87 for cscheme ;;;
- ;;; by Steve Sherin--U of P ;;;
- ;;; File : meth2.scm ;;;
- ;;; ;;;
- ;;; Amitabh Srivastava ;;;
- ;;; ;;;
- ;;; This file handles the deletion of a method from a class. ;;;
- ;;; ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;;; DELETE-METHOD
- (syntax-table-define user-initial-syntax-table 'delete-method
- (macro e
- (let ((class-name (caar e))
- (method-name (cadar e)))
- `(%sc-class-del-method
- ',class-name
- ',method-name
- ',class-name
- ',class-name
- (LAMBDA (ENV VAL)
- (SET! (ACCESS ,method-name ENV) VAL))
- #f))))
- ;;;
-
- (define %deleted-method
- (lambda (name)
- (lambda args
- (error-handler name 3 #t))))
- ;;;
-
- (define %sc-class-del-method
- (lambda (class-name method-name method-class mixin-class assigner del-value)
- (let ((class (%sc-name->class class-name)))
- (let ((temp (assq method-name (%sc-method-values class))))
- (if temp
- (begin
- (%sc-set-method-values class
- (delq! temp (%sc-method-values class)))
- (%compiled-del-method class-name method-name method-class mixin-class
- assigner del-value))
-
- (error-handler method-name 4 #t))))))
- ;;;
-
- (define %inform-del-subclasses
- (lambda (class-name method-name method-class mixin-class assigner del-value)
- (define loop
- (lambda (class-name method-name method-class mixin-class assigner
- del-value subclass)
- (if subclass
- (begin
- (%compiled-del-method (car subclass) method-name
- method-class class-name assigner del-value)
- (loop class-name method-name method-class mixin-class assigner
- del-value (cdr subclass))))))
- (loop class-name method-name method-class mixin-class assigner del-value
- (%sc-subclasses (%sc-name->class class-name)))))
- ;;;
-
- (define %compiled-del-method
- (lambda (class-name method-name method-class mixin-class assigner del-value)
- (let ((class (%sc-name->class class-name)))
- (letrec
- ((delete-entry
- (lambda (previous current)
- (cond ((eq? mixin-class (cdar current))
- (set-cdr! previous (cdr current)) #t)
- (else #f))))
-
- (loop-delete
- (lambda (previous current)
- (cond ((or (null? current)
- (%before mixin-class (cdar previous)
- class-name))
- (error-handler method-name 4 #t))
- ((delete-entry previous current) #t)
- (else (loop-delete current (cdr current))))))
-
- (delete
- (lambda (entry)
- (if (delete-entry entry (cdr entry)) ;;; delete at head
- (modify-environment entry)
- (loop-delete (cdr entry) (cddr entry)))))
-
- (modify-environment
- (lambda (entry)
- (cond ((null? (cdr entry))
- (%sc-set-method-structure class
- (delq! (assq method-name (%sc-method-structure class))
- (%sc-method-structure class)))
- (if (%sc-class-compiled class)
- (assigner (%sc-method-env class)
- (or del-value
- (set! del-value
- (%deleted-method method-name)))))
- (if (%sc-subclasses class)
- (%inform-del-subclasses class-name method-name
- method-class mixin-class assigner del-value)))
- (else
- (let ((meth-value
- (%sc-get-meth-value method-name
- (%sc-name->class (caadr entry)))))
- (if (%sc-class-compiled class)
- (assigner (%sc-method-env class) meth-value))
- (if (%sc-subclasses class)
- (%inform-subclasses class-name
- method-name
- method-class
- mixin-class
- meth-value assigner)))))))
- )
-
- (let ((method-entry (assq method-name (%sc-method-structure class))))
- (if method-entry
- (delete method-entry)
- (error-handler method-name 4 #t))
- method-name)))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; ;;;
- ;;; S c o o p s ;;;
- ;;; ;;;
- ;;; ;;;
- ;;; Rewritten 5/20/87 for cscheme ;;;
- ;;; by Steve Sherin--U of P ;;;
- ;;; File : instance.scm ;;;
- ;;; ;;;
- ;;; Amitabh Srivastava ;;;
- ;;; ;;;
- ;;; This file contains compiling and making of an instance. ;;;
- ;;; ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;;; COMPILE-CLASS
- (syntax-table-define user-initial-syntax-table 'compile-class
- (macro e
- `(let* ((class ,(car e))
- (name (%sc-name class)))
- (if (%sc-class-compiled class)
- name
- (begin
- (%inherit-method-vars class)
- (eval (%make-template name class) (the-environment)))))))
- ;;;
-
- (define (%sc-compile-class class)
- (begin
- (%inherit-method-vars class)
- (eval (%make-template (%sc-name class) class)
- user-initial-environment)))
-
- ;;; MAKE-INSTANCE
- (syntax-table-define user-initial-syntax-table 'make-instance
- (macro e
- (cons (list '%sc-inst-template (car e)) (cdr e))))
- ;;;
-
- (define %uncompiled-make-instance
- (lambda (class)
- (lambda init-msg
- (%sc-compile-class class)
- (apply (%sc-inst-template class) init-msg))))
- ;;;
-
- (define %make-template
- (lambda (name class)
- `(begin
- ;;; do some work to make compile-file work
- (%sc-set-allcvs ,name ',(%sc-allcvs class))
- (%sc-set-allivs ,name ',(%sc-allivs class))
- (%sc-set-method-structure ,name
- ',(%sc-method-structure class))
- ;;; prepare make-instance template
- (%sc-set-inst-template ,name
- ,(%make-inst-template (%sc-allcvs class)
- (%sc-allivs class)
- (%sc-method-structure class)
- name class))
- (%sc-method-thrust ,name)
- (%sc-set-class-compiled ,name #t)
- (%sc-set-class-inherited ,name #t)
- (%sign-on ',name ,name)
- ',name)))
- ;;;
-
- (define %make-inst-template
- (lambda (cvs ivs method-structure name class)
- (let ((methods '((%*methods*% '-)))
- (classvar (append cvs '((%*classvars*% '-))))
- (instvar (append ivs '((%*instvars*% '-)))))
- ;;; dummy variables are added to methods, cvs, and ivs to prevent the
- ;;; compiler from folding them away.
- `(let ,classvar
- (%sc-set-class-env ,name (the-environment))
- (let ,methods
- (%sc-set-method-env ,name (the-environment))
- (let ((%sc-class ,name))
- (lambda %sc-init-vals
- (let ,instvar
- (the-environment)))))))))
-
-
-
- ;;; %sc-method-thrust evaluates each method in the method-environment
- ;;; for the class, enabling methods to grab free variables from the
- ;;; class-environment without a special code-replacement call.
-
- (define (%sc-method-thrust class)
- (define (iter binding-pair)
- (let* ((method-name (car binding-pair))
- (quoted-val
- (cdr (assq method-name
- (%sc-method-values (%sc-name->class
- (caadr binding-pair))))))
- (temp `(in-package (%sc-method-env class)
- (define ,method-name ,quoted-val))))
- (eval temp (the-environment))))
- (map iter (%sc-method-structure class)))
-
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; ;;;
- ;;; S c o o p s ;;;
- ;;; ;;;
- ;;; ;;;
- ;;; Rewritten 5/20/87 for cscheme ;;;
- ;;; by Steve Sherin--U of P ;;;
- ;;; File : inht.scm ;;;
- ;;; ;;;
- ;;; Amitabh Srivastava ;;;
- ;;; ;;;
- ;;; This file contains routines to handle inheritance. ;;;
- ;;; ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;;;
-
- (define %inherit-method-vars
- (lambda (class)
- (or (%sc-class-inherited class)
- (%inherit-from-mixins
- (%sc-allcvs class)
- (%sc-allivs class)
- (%sc-method-structure class)
- (%sc-mixins class)
- class
- (lambda (class cvs ivs methods)
- (%sc-set-allcvs class cvs)
- (%sc-set-allivs class ivs)
- (%sc-set-method-structure class methods)
- (%sc-set-class-inherited class #t)
- (%sign-on (%sc-name class) class)
- class)))))
- ;;;
-
- (define %sign-on
- (lambda (name class)
- (map
- (lambda (mixin)
- (let* ((mixin-class (%sc-name->class mixin))
- (subc (%sc-subclasses mixin-class)))
- (if (not (%sc-class-inherited mixin-class))
- (%inherit-method-vars mixin-class))
- (or (memq name subc)
- (%sc-set-subclasses mixin-class (cons name subc)))))
- (%sc-mixins class))))
- ;;;
-
- (define %inherit-from-mixins
- (letrec
- ((insert-entry
- (lambda (entry class1 method-entry name2 previous current)
- (cond ((null? current)
- (set-cdr! previous
- (cons (cons (caadr method-entry) name2) '())))
- ((%before name2 (cdar current) (%sc-name class1))
- (set-cdr! previous
- (cons (cons (caadr method-entry) name2) current)))
- (else '()))))
-
- (insert
- (lambda (struct1 entry class1 struct2 name2)
- (define loop-insert
- (lambda (struct1 entry class1 struct2 name2 previous current)
- (if (insert-entry entry class1 struct2 name2 previous current)
- struct1
- (loop-insert struct1 entry class1 struct2 name2
- current (cdr current)))))
- (loop-insert struct1 entry class1 struct2 name2 entry (cdr entry))))
-
- (add-entry
- (lambda (struct1 class1 method-entry name2)
- (cons (list (car method-entry) (cons (caadr method-entry) name2))
- struct1)))
-
- (combine-methods
- (lambda (struct1 class1 struct2 name2)
- (if struct2
- (combine-methods
- (let ((entry (assq (caar struct2) struct1)))
- (if entry
- (insert struct1 entry class1 (car struct2) name2)
- (add-entry struct1 class1 (car struct2) name2)))
- class1
- (cdr struct2)
- name2)
- struct1)))
-
- (combine-vars
- (lambda (list1 list2)
- (if list2
- (combine-vars
- (if (assq (caar list2) list1)
- list1
- (cons (car list2) list1))
- (cdr list2))
- list1)))
- )
-
- (lambda (cvs ivs methods mixins class receiver)
- (define loop-mixins
- (lambda (cvs ivs methods mixins class receiver)
- (if mixins
- (let ((mixin-class (%sc-name->class (car mixins))))
- (%inherit-method-vars mixin-class)
- (loop-mixins
- (combine-vars cvs (%sc-allcvs mixin-class))
- (combine-vars ivs (%sc-allivs mixin-class))
- (combine-methods methods class
- (%sc-method-structure mixin-class) (car mixins))
- (cdr mixins)
- class
- receiver))
- (receiver class cvs ivs methods ))))
- (loop-mixins cvs ivs methods mixins class receiver))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; ;;;
- ;;; S c o o p s ;;;
- ;;; ;;;
- ;;; ;;;
- ;;; Rewritten 5/20/87 for cscheme ;;;
- ;;; by Steve Sherin--U of P ;;;
- ;;; File : interf.scm ;;;
- ;;; ;;;
- ;;; Amitabh Srivastava ;;;
- ;;; ;;;
- ;;; This file contains class definition and processing of ;;;
- ;;; define-class. ;;;
- ;;; ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (define (oddmemq obj list)
- (cond ((not (pair? list)) #f)
- ((not (pair? (cdr list))) #f)
- ((eq? obj (car list)) list)
- (else (oddmemq obj (cddr list)) )))
-
- ;;; DEFINE-CLASS
- (syntax-table-define user-initial-syntax-table 'define-class
- (macro e
- (let ((name (car e))
- (classvars '())
- (instvars '()) (mixins '())
- (options '())
- (allvars '())
- (method-values '())(inits '()))
- (letrec
- ((chk-class-def
- (lambda (deflist)
- (if deflist
- (begin
- (cond ((eq? (caar deflist) 'classvars)
- (set! classvars (cdar deflist)))
- ((eq? (caar deflist) 'instvars)
- (set! instvars (cdar deflist)))
- ((eq? (caar deflist) 'mixins)
- (set! mixins (cdar deflist)))
- ((eq? (caar deflist) 'options)
- (set! options (cdar deflist)))
- (else (error-handler (caar deflist) 0 '())))
- (chk-class-def (cdr deflist)))
- (update-allvars))))
-
- (update-allvars
- (lambda ()
- (set! allvars
- (append (map (lambda (a) (if (symbol? a) a (car a)))
- classvars)
- (map (lambda (a) (if (symbol? a) a (car a)))
- instvars)))))
-
-
- (chk-option
- (lambda (opt-list)
- (let loop ((opl opt-list)(meths '()))
- (if opl
- (loop
- (cdr opl)
- (cond ((eq? (caar opl) 'gettable-variables)
- (append (generate-get (cdar opl)) meths))
- ((eq? (caar opl) 'settable-variables)
- (append (generate-set (cdar opl)) meths))
- ((eq? (caar opl) 'inittable-variables)
- (set! inits (cdar opl)) meths)
- (else (error-handler (car opl) 1 '()))))
- meths))))
-
- (chk-cvs
- (lambda (list-var)
- (map
- (lambda (a)
- (if (symbol? a)
- (list a #f)
- a))
- list-var)))
-
- (chk-init
- (lambda (v-form)
- (if (memq (car v-form) inits)
- `(,(car v-form)
- (let ((temp (oddmemq ',(car v-form) %sc-init-vals)))
- ;was '%sc-init-vals
- (if temp (cadr temp)
- ,(cadr v-form))))
- v-form)))
-
- (chk-ivs
- (lambda (list-var)
- (map
- (lambda (var)
- (chk-init
- (cond ((symbol? var) (list var #f))
- ((not-active? (cadr var)) var)
- (else (active-val (car var) (cadr var))))))
- list-var)))
-
- (not-active?
- (lambda (a)
- (or (not (pair? a))
- (not (eq? (car a) 'active)))))
-
- (empty-slot?
- (lambda (form)
- (cond
- ((symbol? form) #f)
- ((eq? form #f) #t)
- (else #f))))
-
- (active-val
- (lambda (var active-form)
- (let loop ((var var)(active-form active-form)
- (getfns '())(setfns '%sc-val))
- (if (not-active? (cadr active-form))
- (create-active
- var
- (if (empty-slot? (caddr active-form))
- getfns
- (cons (caddr active-form) getfns))
- (list 'set! var
- (if (empty-slot? (cadddr active-form))
- setfns
- (list (cadddr active-form) setfns)))
- (cadr active-form))
- (loop
- var
- (cadr active-form)
- (if (empty-slot? (caddr active-form))
- getfns
- (cons (caddr active-form) getfns))
- (if (empty-slot? (cadddr active-form))
- setfns
- (list (cadddr active-form) setfns)))))))
-
- (create-active
- (lambda (var getfns setfns localstate)
- (begin
- (set! method-values
- (cons `(CONS ',(concat "GET-" var)
- (list 'lambda '() ',(expand-getfns var getfns)))
- (cons `(CONS ',(concat "SET-" var)
- (list 'lambda (list '%sc-val)
- ',setfns))
- method-values)))
- (list var localstate))))
-
- (expand-getfns
- (lambda (var getfns)
- (let loop ((var var)(gets getfns)(exp-form var))
- (if gets
- (loop
- var
- (cdr gets)
- (list (car gets) exp-form))
- exp-form))))
- (concat
- (lambda (str sym)
- (intern (string-append str (symbol->string sym)))))
-
- (generate-get
- (lambda (getlist)
- (map
- (lambda (a)
- `(CONS ',(concat "GET-" a)
- (list 'lambda '()
- ',a)))
- getlist)))
-
- (generate-set
- (lambda (setlist)
- (map
- (lambda (a)
- `(CONS ',(concat "SET-" a)
- (list 'lambda (list '%sc-val)
- (list 'set! ',a '%sc-val))))
- setlist)))
-
- )
-
- ;; define-class begins here.
-
- (begin
- (chk-class-def (cdr e))
- (set! method-values
- (chk-option
- (map (lambda (a) (if (symbol? a) (cons a allvars) a))
- options)))
- (set! instvars (and instvars (chk-ivs instvars)))
- ;; Evaluate here so that active-value functions are generated properly.
- ;; --Steve Sherin
- (set! classvars (and classvars (chk-cvs classvars)))
- (eval
- `(DEFINE ,name
- (%SC-MAKE-CLASS
- ',name
- ',classvars
- ',instvars
- ',mixins
- ,(and method-values (cons 'list method-values))
- ))
- user-initial-environment)
- )))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; ;;;
- ;;; S c o o p s ;;;
- ;;; ;;;
- ;;; ;;;
- ;;; Rewritten 5/20/87 for cscheme ;;;
- ;;; by Steve Sherin--U of P ;;;
- ;;; File : send.scm ;;;
- ;;; ;;;
- ;;; Amitabh Srivastava ;;;
- ;;; ;;;
- ;;;-----------------------------------------------------------------;;;
- ;;; One does not have to use the SEND form to invoke methods ;;;
- ;;; in the same class; they can be invoked as Scheme functions. ;;;
- ;;; ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;;; SEND
- (define-macro-both (send . e)
- (let ((args (cddr e))
- (msg (cadr e))
- (obj (car e)))
- `(let* ((set-parent! (access ic-environment/set-parent!
- environment-package))
- (ep environment-parent)
- (ibot ,obj)
- (itop (ep (ep ibot)))
- (ipar (ep itop))
- (class (access %sc-class ibot))
- (ctop (%sc-class-env class))
- (cpar (ep ctop))
- (cbot (%sc-method-env class))
- (instance-safe? (eq? ipar cbot)))
-
- (without-interrupts
- (lambda ()
- (dynamic-wind
- (lambda ()
- (set-parent! ctop ibot)
- (if instance-safe?
- (set-parent! itop cpar)))
-
-
- (lambda ()
- ;; I think that the next line should really be
- ;; ((environment-lookup cbot ',msg) ,@args))
- ;; -markf
- (in-package cbot (,msg ,@args)))
-
- (lambda ()
- (set-parent! ctop cpar)
- (set-parent! itop cbot))
- ))))))
-
-
- ;;; SEND-IF-HANDLES
- (syntax-table-define user-initial-syntax-table 'send-if-handles
- (macro e
- (let ((obj (car e))
- (msg (cadr e))
- (args (cddr e)))
- `(let
- ((self ,obj))
-
- (if (assq ',msg (%sc-method-structure (access %sc-class self)))
- (send self ,msg ,@args)
- #f)))))
-
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; ;;;
- ;;; S c o o p s ;;;
- ;;; ;;;
- ;;; ;;;
- ;;; Rewritten 5/20/87 for cscheme ;;;
- ;;; by Steve Sherin--U of P ;;;
- ;;; File : utl.scm ;;;
- ;;; ;;;
- ;;; Amitabh Srivastava ;;;
- ;;; ;;;
- ;;; This file contains misc. routines ;;;
- ;;; ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
- ;;; Error handler. Looks up the error message in the table and
- ;;; prints it.
-
- (define error-handler
- (let ((error-table
- (let ((table (make-vector 8)))
- (vector-set! table 0 " Invalid class definition ")
- (vector-set! table 1 " Invalid option ")
- (vector-set! table 2 " Class not defined ")
- (vector-set! table 3 " Method has been deleted ")
- (vector-set! table 4 " Method is not present ")
- (vector-set! table 5 " Variable is not present")
- (vector-set! table 6 " Not a Scoops Class")
- (vector-set! table 7 " Class not compiled ")
- table)))
- (lambda (msg number flag)
- (if flag
- (error (vector-ref error-table number) msg)
- (bkpt (vector-ref error-table number) msg)))))
-
-
- ;;; some functions defined globally which will be moved locally later
-
- (define %sc-class-description
- (lambda (class)
- (writeln " ")
- (writeln " CLASS DESCRIPTION ")
- (writeln " ================== ")
- (writeln " ")
- (writeln " NAME : " (%sc-name class))
- (writeln " CLASS VARS : "
- (map car (%sc-allcvs class)))
- (writeln " INSTANCE VARS : "
- (map car (%sc-allivs class)))
- (writeln " METHODS : "
- (map car (%sc-method-structure class)))
- (writeln " MIXINS : " (%sc-mixins class))
- (writeln " CLASS COMPILED : " (%sc-class-compiled class))
- (writeln " CLASS INHERITED : " (%sc-class-inherited class))
- ))
- ;;;
-
- (define %sc-inst-desc
- (lambda (inst)
- (letrec ((class (access %sc-class inst))
- (printvars
- (lambda (f1 f2)
- (if f1 ; another var
- (begin
- (writeln " " (caar f1) " : "
- (cadr (assq (caar f1) f2)))
- ;; environment bindings in list form vs. pair form. Steve Sherin
- (printvars (cdr f1) f2))
- *the-non-printing-object*))))
- (writeln " ")
- (writeln " INSTANCE DESCRIPTION ")
- (writeln " ==================== ")
- (writeln " ")
- (writeln " Instance of Class : " (%sc-name class))
- (writeln " ")
- (writeln " Class Variables : ")
- (printvars (%sc-allcvs class)
- (environment-bindings (%sc-class-env class)))
- (writeln " ")
- (writeln " Instance Variables :")
- (printvars (%sc-allivs class) (environment-bindings inst))
- )))
-
- ;;;
- (define %scoops-chk-class-compiled
- (lambda (name class)
- (or (%sc-class-compiled class)
- (error-handler name 7 #t))))
-
- ;;;
- (define %sc-class-info
- (lambda (fn)
- (lambda (class)
- (%scoops-chk-class class)
- (map car (fn class)))))
-
- ;;; ALL-CLASSVARS
- (set! all-classvars (%sc-class-info %sc-allcvs))
-
- ;;; ALL-INSTVARS
- (set! all-instvars (%sc-class-info %sc-allivs))
-
- ;;; ALL-METHODS
- (set! all-methods (%sc-class-info %sc-method-structure))
-
- ;;; (CLASS-COMPILED? CLASS)
- (set! class-compiled?
- (lambda (class)
- (%scoops-chk-class class)
- (%sc-class-compiled class)))
-
- ;;; (CLASS-OF-OBJECT OBJECT)
- (syntax-table-define user-initial-syntax-table 'class-of-object
- (macro e
- `(%sc-name (access %sc-class ,(car e)))))
-
- ;;; CLASSVARS
- (set! classvars (%sc-class-info %sc-cv))
-
- ;;; DESCRIBE
- (set! describe
- (lambda (class-inst)
- (if (vector? class-inst)
- (begin
- (%scoops-chk-class class-inst)
- (%sc-class-description class-inst))
- (%sc-inst-desc class-inst))))
-
- ;;; (GETCV CLASS VAR)
- (syntax-table-define user-initial-syntax-table 'getcv
- (macro e
- (let ((class (car e))
- (var (cadr e)))
- `(begin
- (and (%sc-name->class ',class)
- (%scoops-chk-class-compiled ',class ,class))
- ((access ,(%sc-concat "GET-" var) (%sc-method-env ,class)))))))
-
- ;;; INSTVARS
- (set! instvars (%sc-class-info %sc-iv))
-
- ;;; METHODS
- (set! methods (%sc-class-info %sc-method-values))
-
- ;;; MIXINS
- (set! mixins
- (lambda (class)
- (%scoops-chk-class class)
- (%sc-mixins class)))
-
- ;;; (NAME->CLASS NAME)
- (syntax-table-define user-initial-syntax-table 'name->class
- (macro e
- `(%sc-name->class ,(car e))))
-
- ;;; (RENAME-CLASS (CLASS NEW-NAME))
- (syntax-table-define user-initial-syntax-table 'rename-class
- (macro e
- (let ((class (caar e))
- (new-name (cadar e)))
- `(begin
- (%sc-name->class ',class)
- (%sc-set-name ,class ',new-name)
- (2d-put! ',new-name '%class ,class)
- (eval '(define ,new-name ,class) user-initial-environment)
- ',new-name))))
-
- ;;; (SETCV CLASS VAR VAL)
- (syntax-table-define user-initial-syntax-table 'setcv
- (macro e
- (let ((class (car e))
- (var (cadr e))
- (val (caddr e)))
- `(begin
- (and (%sc-name->class ',class)
- (%scoops-chk-class-compiled ',class ,class))
- ((access ,(%sc-concat "SET-" var) (%sc-method-env ,class)) ,val)))))
-